package org.my.stock.h2;

import com.google.gson.internal.LinkedTreeMap;
import com.google.gson.reflect.TypeToken;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;
import org.my.stock.util.BrotliHttpClientHelper;
import org.my.stock.util.MyUtil;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ZengChiJianChi {

    public static String getUrl_zeng(String pageNumber) {
        return "https://datacenter-web.eastmoney.com/api/data/v1/get?callback=jQuery112306769455229417962_1751634481371&sortColumns=END_DATE%2CSECURITY_CODE%2CEITIME&sortTypes=-1%2C-1%2C-1&pageSize=50&pageNumber="+ pageNumber +"&reportName=RPT_SHARE_HOLDER_INCREASE&quoteColumns=f2~01~SECURITY_CODE~NEWEST_PRICE%2Cf3~01~SECURITY_CODE~CHANGE_RATE_QUOTES&quoteType=0&columns=ALL&source=WEB&client=WEB&filter=(DIRECTION%3D%22%E5%A2%9E%E6%8C%81%22)";
    }

    public static String getUrl_jian(String pageNumber) {
        return "https://datacenter-web.eastmoney.com/api/data/v1/get?callback=jQuery112306769455229417962_1751634481371&sortColumns=END_DATE%2CSECURITY_CODE%2CEITIME&sortTypes=-1%2C-1%2C-1&pageSize=50&pageNumber="+ pageNumber +"&reportName=RPT_SHARE_HOLDER_INCREASE&quoteColumns=f2~01~SECURITY_CODE~NEWEST_PRICE%2Cf3~01~SECURITY_CODE~CHANGE_RATE_QUOTES&quoteType=0&columns=ALL&source=WEB&client=WEB&filter=(DIRECTION%3D%22%E5%87%8F%E6%8C%81%22)";
    }

    public static String getData(String pageNumber, Boolean isZeng) {
        String content = null;
        String url = null;
        if (isZeng) {
            url = getUrl_zeng(pageNumber);
        } else {
            url = getUrl_jian(pageNumber);
        }
        if (url != null) {
            HttpClient httpClient = BrotliHttpClientHelper.createBrotliClient();

            try {
                // 1. 创建 GET 请求
                HttpGet request = new HttpGet(url);

                // 2. 设置请求头（防止被服务器拒绝）
                request.setHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36");
                request.setHeader("Accept", "*/*");
                request.setHeader("Accept-Encoding", "gzip, deflate, br");
                request.setHeader("Accept-Language", "zh-CN,zh;q=0.9");
                request.setHeader("Cache-Control", "max-age=0");
                request.setHeader("Connection", "keep-alive");
                request.setHeader("Cookie", "em_hq_fls=js; intellpositionL=1140px; em-quote-version=topspeed; intellpositionT=1298px; qgqp_b_id=e04e31a1e6446068e54e0f7808401919; sid=142772185; mtp=1; ct=oFv-pht6ZiYeFSXV2tPdRfkJ0x6ZftJa4X2TKji2eXO0Pl_YBbWxGBEwUTJ4z6N0GPPyYYrAizsB50OwF5PQc3x4HESZOAriGonI9ewh-RikgY0SEGHZcdA5RKg5RB4dPVIr3TCQLKkZkYOXQKFQElZVysNazqJ5O7csdsQO8U8; ut=FobyicMgeV5FJnFT189SwH2JOfiEw7mPz0LG7-oku6sFYOCxdbsEi2cnDTMMTwLC08VTgq_y28iF-S7gffFe0HKuLD1gS302VWRzT3pl7pFn5lPVWP0FGEkMzX3xkH4zZ26gwPXYW-E0EBZ8yNwMjA61nTdT3wPUm2MO4K_-pv5FU7C4OKwrxdk0UuppgrEnJEgArYW9ONwiZM25_K7mvoROgdu_rvCGeunwxnPYxpGqdl5zugvVg1iYtj7NhgcPysSINh74Fg1SOz2r1EMofNQ2h17qfzYUEa1h5_9kJkiB1FoE_P6A7kqYkMsr92-xF4fQoC_luUS273FRQNpqdmsbdOgZn9GV; pi=5274385825271944%3Bc5274385825271944%3B%E6%97%A0%E9%87%8F%E7%AB%A5%E5%AD%90%3BdCmpCdx6Fv0K9ySmGo1L60bQl9guPYNF9kW50ggeyA%2BOOeqCGeepIZPP0w088pbSCmH3QEBcYqyucZR9kKKJ4yNWHFBnnJznMgN%2F0PAMxp8Q%2FuJWZ89w97SHWrysOsb%2B93O45rM%2BhQroFhMO0X604MpHaHC%2F9yVsQmkbCVr5W1pviVaJGTOj%2FDWWzVmDAqUqGJzUNqW2%3BYeT6DxMds0uwdT3PftF0xut%2B1faguRkAY5Rpcphp0hhNyyGaYsTQbiMZEJxNWp7SrYuMigne0BGrZhWVS5SuyPZkN9SQHEd8yzBJUAbFcxV2So8rHP9l%2FY1Cf50pniZsBXw%2Bk0GvzjRxxPfbt9j1Vj8dTOWabw%3D%3D; vtpst=%7C; uidal=5274385825271944%E6%97%A0%E9%87%8F%E7%AB%A5%E5%AD%90; xsb_history=872107%7C%u660A%u534E%u80A1%u4EFD; emshistory=%5B%22%E6%BD%9E%E5%AE%89%E7%8E%AF%E8%83%BD%22%2C%22%E5%90%8C%E5%BF%83%E4%BC%A0%E5%8A%A8%22%2C%22%E5%9B%BA%E6%80%81%E7%94%B5%E6%B1%A0%22%2C%22%E8%83%BD%E6%BA%90%E9%87%91%E5%B1%9E%22%2C%22%E6%99%B6%E6%96%B9%E7%A7%91%E6%8A%80%22%2C%22%E5%B9%B3%E5%AE%89%E9%93%B6%E8%A1%8C%22%2C%22%E5%8D%9A%E8%BF%81%E6%96%B0%E6%9D%90%22%2C%22%E4%B8%87%E6%B6%A6%E6%96%B0%E8%83%BD%22%2C%22%E4%BC%9F%E5%88%9B%E7%94%B5%E6%B0%94%22%2C%22%E6%B4%9B%E9%98%B3%E9%92%BC%E4%B8%9A%22%5D; fullscreengg=1; fullscreengg2=1; st_si=15112213441014; HAList=ty-0-000425-%u5F90%u5DE5%u673A%u68B0%2Cty-1-603195-%u516C%u725B%u96C6%u56E2%2Cty-1-600846-%u540C%u6D4E%u79D1%u6280%2Cty-1-601699-%u6F5E%u5B89%u73AF%u80FD%2Cty-90-BK0603-%u9875%u5CA9%u6C14%2Cty-1-600585-%u6D77%u87BA%u6C34%u6CE5%2Cty-1-688685-%u8FC8%u4FE1%u6797%2Cty-1-688225-%u4E9A%u4FE1%u5B89%u5168%2Cty-1-603666-%u4EBF%u5609%u548C%2Cty-1-601799-%u661F%u5B87%u80A1%u4EFD; st_asi=delete; st_pvi=18633756697256; st_sp=2021-05-13%2015%3A20%3A17; st_inirUrl=https%3A%2F%2Fcn.bing.com%2F; st_sn=12; st_psi=20250705205926459-113200301201-7566622313; JSESSIONID=85E6B1148AC6E8EAC2CA66E1C6B4D7EA");
                request.setHeader("Host", "datacenter-web.eastmoney.com");
                request.setHeader("Referer", "https://data.eastmoney.com/executive/gdzjc.html");
                request.setHeader("Sec-Fetch-Dest", "script");
                request.setHeader("Sec-Fetch-Mode", "no-cors");
                request.setHeader("Sec-Fetch-Site", "same-site");

                // 3. 执行请求并获取响应
                HttpResponse response = httpClient.execute(request);

                // 4. 检查状态码
                //int statusCode = response.getStatusLine().getStatusCode();
                //System.out.println("所属类型: " + symbol);

                // 5. 读取响应内容
                HttpEntity entity = response.getEntity();
                if (entity != null) {

                    // 关键：使用 UTF-8 编码转换解压后的字节流
                    content = EntityUtils.toString(entity, "UTF-8");
                    //toDb_ex(conn, content, symbol);
                    System.out.println("解码内容:\n" + content);
                }

            } catch (Exception e) {
                System.err.println("请求失败: " + e.getMessage());
            } finally {
                // 6. 释放连接（重要！）
                httpClient.getConnectionManager().shutdown();
            }
        }
        return content;
    }

    public static String tichu(String result) {
        char[] chs = result.toCharArray();
        StringBuilder sb = new StringBuilder();
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < chs.length; i++) {

            if (chs[i] == ')') {
                stack.pop();
            }

            if (!stack.empty()) {
                //lst.add(chs[i]);
                sb.append(chs[i]);
            }

            if (chs[i] == '(') {
                stack.push(chs[i]);
            }
        }

        return sb.toString();
    }

    public static void toDb_zeng(final String line) throws SQLException {
        String result = tichu(line); // 获取第一个捕获组内容

        LinkedTreeMap m = MyUtil.getGson().fromJson(result, new TypeToken<LinkedTreeMap>() {}.getType());
        LinkedTreeMap data = (LinkedTreeMap) m.get("result");
        List klines = (List) data.get("data");
        //String name = (String) data.get("name");

        for (int i = 0; i < klines.size(); i++) {
            LinkedTreeMap r = (LinkedTreeMap) klines.get(i);
            System.out.println(r.get("SECURITY_CODE").toString() + " " + r.get("SECURITY_NAME_ABBR").toString());
        }
    }

    public static void toDb_jian(final String line) throws SQLException {
        String result = tichu(line); // 获取第一个捕获组内容

        LinkedTreeMap m = MyUtil.getGson().fromJson(result, new TypeToken<LinkedTreeMap>() {}.getType());
        LinkedTreeMap data = (LinkedTreeMap) m.get("result");
        List klines = (List) data.get("data");
        //String name = (String) data.get("name");

        for (int i = 0; i < klines.size(); i++) {
            LinkedTreeMap r = (LinkedTreeMap) klines.get(i);
            System.out.println(r.get("SECURITY_CODE").toString() + " " + r.get("SECURITY_NAME_ABBR").toString());
        }
    }

    public static void toDb_zeng(final Connection conn, final String line) throws SQLException {
        String result = tichu(line); // 获取第一个捕获组内容

        LinkedTreeMap m = MyUtil.getGson().fromJson(result, new TypeToken<LinkedTreeMap>() {}.getType());
        LinkedTreeMap data = (LinkedTreeMap) m.get("result");
        List klines = (List) data.get("data");
        //String name = (String) data.get("name");

        for (int i = 0; i < klines.size(); i++) {
            LinkedTreeMap r = (LinkedTreeMap) klines.get(i);
            System.out.println(r.get("SECURITY_CODE").toString() + " " + r.get("SECURITY_NAME_ABBR").toString());
            update_zeng(conn, r.get("SECURITY_CODE").toString(), r.get("SECURITY_NAME_ABBR").toString());
        }
    }

    public static void toDb_jian(final Connection conn, final String line) throws SQLException {
        String result = tichu(line); // 获取第一个捕获组内容

        LinkedTreeMap m = MyUtil.getGson().fromJson(result, new TypeToken<LinkedTreeMap>() {}.getType());
        LinkedTreeMap data = (LinkedTreeMap) m.get("result");
        List klines = (List) data.get("data");
        //String name = (String) data.get("name");

        for (int i = 0; i < klines.size(); i++) {
            LinkedTreeMap r = (LinkedTreeMap) klines.get(i);
            System.out.println(r.get("SECURITY_CODE").toString() + " " + r.get("SECURITY_NAME_ABBR").toString());
            update_jian(conn, r.get("SECURITY_CODE").toString(), r.get("SECURITY_NAME_ABBR").toString());
        }
    }

    public static void update_jian(Connection conn, String symbol, String name) throws SQLException {
        // 修改最后一项的数据
        Boolean flag = getJian(conn, symbol);
        if (flag == false) {
            String sql = "insert into jian_chi (symbol, name) values ('" + symbol + "', '" + name + "')";
            Statement stmt = conn.createStatement();
            stmt.execute(sql);
        }
    }

    public static void update_zeng(Connection conn, String symbol, String name) throws SQLException {
        // 修改最后一项的数据
        Boolean flag = getZeng(conn, symbol);
        if (flag == false) {
            String sql = "insert into zeng_chi (symbol, name) values ('" + symbol + "', '" + name + "')";
            Statement stmt = conn.createStatement();
            stmt.execute(sql);
        }
    }

    /**
     * 获取是否有增持
     * */
    public static Boolean getZeng(Connection conn, String symbol) {
        String sql = "select symbol from zeng_chi where symbol = '"+ symbol +"'";
        PreparedStatement stmt = null;
        ResultSet rs = null;
        Boolean flag = false;

        try {
            stmt = conn.prepareStatement(sql);

            // 5. 执行查询并获取结果集
            rs = stmt.executeQuery();

            // 6. 遍历结果集并处理数据
            while (rs.next()) {
                flag = true;
            }

        } catch (SQLException e) {
            System.err.println("数据库操作失败！错误信息：" + e.getMessage());
            e.printStackTrace();
        } finally {
            // 7. 关闭资源（反向顺序）
            try {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        return flag;
    }

    /**
     * 获取是否有减持
     * */
    public static Boolean getJian(Connection conn, String symbol) {
        String sql = "select symbol from jian_chi where symbol = '"+ symbol +"'";
        PreparedStatement stmt = null;
        ResultSet rs = null;
        Boolean flag = false;

        try {
            stmt = conn.prepareStatement(sql);

            // 5. 执行查询并获取结果集
            rs = stmt.executeQuery();

            // 6. 遍历结果集并处理数据
            while (rs.next()) {
                flag = true;
            }

        } catch (SQLException e) {
            System.err.println("数据库操作失败！错误信息：" + e.getMessage());
            e.printStackTrace();
        } finally {
            // 7. 关闭资源（反向顺序）
            try {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        return flag;
    }

    /**
     * 增持
     * */
    public static void zengChi() throws SQLException, ClassNotFoundException {
        Connection conn = MyUtil.getConnection();
        for (int i = 1; i < 11; i++) {
            String content = getData(String.valueOf(i), true);
            toDb_zeng(conn, content);
        }
    }

    /**
     * 减持
     * */
    public static void jianChi() throws SQLException, ClassNotFoundException {
        Connection conn = MyUtil.getConnection();
        for (int i = 1; i < 11; i++) {
            String content = getData(String.valueOf(i), false);
            toDb_jian(conn, content);
        }
    }
}

















































